/**
 * FileName: JwtUtils
 * Author: Mr.Wang
 * Date: 2025/10/17 11:03
 * Description:
 * History:
 */
package org.test.device.config.jwt;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author Mr.Wang
 * @create 2025/10/17
 * @since 1.0.0
 */
@Data
@Component
@ConfigurationProperties(prefix = "jwt")
public class JwtUtils {

    // 注入Access Token配置
    @Value("${jwt.access.secret-key}")
    private String accessSecretKey;
    @Value("${jwt.access.expire-time}")
    private long accessExpireTime;

    // 注入Refresh Token配置
    @Value("${jwt.refresh.secret-key}")
    private String refreshSecretKey;
    @Value("${jwt.refresh.expire-time}")
    private long refreshExpireTime;

    /**
     * 生成Access Token（短期，用于接口鉴权）
     * @param userId 用户ID（从数据库查询的唯一标识）
     * @param role 用户角色（如ADMIN/USER，用于权限控制）
     */
    public String generateAccessToken(Long userId, String role) {
        return Jwts.builder()
                .setSubject(userId.toString()) // 存入用户ID（字符串格式，便于解析）
                .claim("role", role)            // 存入用户角色（自定义字段）
                .setIssuedAt(new Date())        // 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + accessExpireTime)) // 过期时间
                .signWith(SignatureAlgorithm.HS256, accessSecretKey) // 签名算法+密钥
                .compact();
    }

    /**
     * 生成Refresh Token（长期，用于刷新Access Token）
     * @param userId 用户ID
     */
    public String generateRefreshToken(Long userId) {
        return Jwts.builder()
                .setSubject(userId.toString())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + refreshExpireTime))
                .signWith(SignatureAlgorithm.HS256, refreshSecretKey)
                .compact();
    }

    /**
     * 解析Access Token，获取用户ID
     * @param accessToken 待解析的Access Token
     * @return 用户ID（Long类型）
     */
    public Long getUserIdFromAccessToken(String accessToken) {
        Claims claims = parseAccessTokenClaims(accessToken);
        return Long.parseLong(claims.getSubject());
    }

    /**
     * 解析Refresh Token，获取用户ID
     */
    public Long getUserIdFromRefreshToken(String refreshToken) {
        Claims claims = parseRefreshTokenClaims(refreshToken);
        return Long.parseLong(claims.getSubject());
    }

    /**
     * 验证Access Token有效性（签名+未过期）
     */
    public boolean validateAccessToken(String accessToken) {
        try {
            parseAccessTokenClaims(accessToken);
            return true;
        } catch (JwtException | IllegalArgumentException e) {
            return false;
        }
    }

    /**
     * 验证Refresh Token有效性
     */
    public boolean validateRefreshToken(String refreshToken) {
        try {
            parseRefreshTokenClaims(refreshToken);
            return true;
        } catch (JwtException | IllegalArgumentException e) {
            return false;
        }
    }

    // 私有方法：解析Access Token的Claims（包含用户信息、过期时间等）
    private Claims parseAccessTokenClaims(String accessToken) {
        return Jwts.parserBuilder()
                .setSigningKey(accessSecretKey)
                .build()
                .parseClaimsJws(accessToken)
                .getBody();
    }

    // 私有方法：解析Refresh Token的Claims
    private Claims parseRefreshTokenClaims(String refreshToken) {
        return Jwts.parserBuilder()
                .setSigningKey(refreshSecretKey)
                .build()
                .parseClaimsJws(refreshToken)
                .getBody();
    }
}